import re
from django.core.mail import send_mail
from django_redis import get_redis_connection
from rest_framework import fields, serializers
from django.contrib.auth import get_user_model
from django.conf import settings
# from rest_framework_jwt.views import obtain_jwt_token
from rest_framework_jwt.settings import api_settings

from celery_tasks.email.tasks import send_verify_email


class UserSerializer(serializers.ModelSerializer):
    sms_code = serializers.IntegerField(label="验证码", write_only=True)
    agreement = serializers.BooleanField(label="同意协议", write_only=True)
    password2 = serializers.CharField(label="确认密码", write_only=True)
    token = serializers.CharField(label='Token', read_only=True)

    class Meta:
        model = get_user_model()
        fields = ("id", "username", "mobile", "sms_code", "agreement", "password", "password2", "token",)
        extra_kwargs = {"username": {"min_length": 3, "max_length": 33, }, "password": {"write_only": True}, }

    def create(self, validated_data):
        password = validated_data["password"]
        del validated_data["password2"]
        del validated_data["agreement"]
        del validated_data["sms_code"]

        new_user = get_user_model()(**validated_data)

        new_user.set_password(password)
        new_user.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(new_user)
        token = jwt_encode_handler(payload)
        new_user.token = token

        return new_user

    def validate(self, attrs):
        try:
            if get_user_model().objects.filter(mobile__exact=str(attrs["mobile"])):
                raise serializers.ValidationError
            if get_user_model().objects.filter(username__exact=attrs["username"]):
                raise serializers.ValidationError
            if not attrs["agreement"]:
                raise serializers.ValidationError
            if not re.match(r"1\d{10}", str(attrs["mobile"])):
                raise serializers.ValidationError
            if attrs["password"] != attrs["password2"]:
                raise serializers.ValidationError
            redis_conn = get_redis_connection("verify_codes")
            if str(attrs["sms_code"]) != redis_conn.get("sms_" + str(attrs["mobile"])).decode():
                raise serializers.ValidationError
        except:
            raise serializers.ValidationError
        return attrs


class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = get_user_model()
        fields = ('mobile', 'id', 'username', 'email', 'email_activated', )
        extra_kwargs = {
            'email': {'required': True, },
            'id': {'read_only': True, },
            'mobile': {'read_only': True, },
            'username': {'read_only': True, },
            'email_activated': {'read_only': True, },
        }

    def update(self, instance, validated_data):
        # send email here!!!
        # send_mail(subject="confirm email", message='message', from_email=settings.EMAIL_HOST_USER, recipient_list=[validated_data['email']])
        # send_verify_email.delay(validated_data['email'], verify_url='xxxx')
        send_verify_email.delay([validated_data['email'], ], get_user_model().get_verify_url(instance))
        return super().update(instance, validated_data)
